<HEAD>
  <SCRIPT SRC="../ganja.js"></SCRIPT>
</HEAD>
<BODY><SCRIPT>
// Create a Clifford Algebra with 9,6 metric for 3D QCGA. 
Algebra(9,6,()=>{ 

  // http://www-igm.univ-mlv.fr/~vnozick/publications/breuils_ENGAGE_AACA_2018/breuils_ENGAGE_AACA_2018.pdf

  // Quadric Conformal CGA allows for natural generation of quadric objects
  // by wedging 9 points. 
  
  // Defining the null basis - bit cumbersome .. 
    var plus=[1e04,1e05,1e06,1e07,1e08,1e09], min = [1e10,1e11,1e12,1e13,1e14,1e15],
        [ei1,ei2,ei3,ei4,ei5,ei6] = plus+min, [eo1,eo2,eo3,eo4,eo5,eo6] = 0.5*(min-plus);

  // Hexa-orig and inf, Penta-orig and inf, PSS, Euclidean PSS and inverse PSS.
    var pIi = (ei1-ei2)^(ei2-ei3)^ei4^ei5^ei6,  pIo  = (eo1-eo2)^(eo2-eo3)^eo4^eo5^eo6,
        PSS = 1e010203040506070809101112131415, PSSe = 1e010203, PSSi = -PSS;
        
  // Create a quadric conformal point. (written as dot product .. faster)
    var pv = [1e01,1e02,1e03,ei1,ei2,ei3,ei4,ei5,ei6,eo1+eo2+eo3],
        p  = (x,y,z)=> [x,y,z,.5*x**2,.5*y**2,.5*z**2,x*y,x*z,y*z,1]*pv;          
  
  // for the viz, we need the same in pure basis blades. (all coeffs as func of x,y,z)
    var pviz = p(Element.Scalar("x"),Element.Scalar("y"),Element.Scalar("z")).Vector;

  // Create some points. 
    var p1=p(0,1,0), p2=p(0,-1,0), p3=p(1,0,0), p4=p(0,0,1);
    var q1=p(0,1.5+.35,.5), q2=p(0,-.5+.35,.5), q3=p(1.3,.5+.35,.5), q4=p(0,.5+.35,1.6);
    
  // wedge them into a quadriconformal sphere, next tweak into ellipsoid (grade 14)
    var sphere = (p1^p2^p3^p4^pIi^pIo).Normalized, sphere2 = (q1^q2^q3^q4^pIi^pIo).Normalized;
    sphere[14][10]*=.2; sphere[14][11]*=6; sphere = sphere.Normalized;
    sphere2[14][12]*=.4; sphere2[14][10]*=8; sphere2 = sphere2.Normalized;
    
  // Graph and animate
    document.body.appendChild(this.graph(()=>{
      var s = 0+sphere, s2 = 0+sphere2;                    // copy originals
      s[14][4]+=0.2*Math.sin(performance.now()/1000);      // animate
      s[14][10]+=0.1+Math.sin(performance.now()/1491);
      s2[14][11]+=0.5*Math.sin(performance.now()/790);
      s2[14][13]+=Math.sin(performance.now()/1300);
      var c = (s&s2).Normalized;                           // intersect
      return [0x8800ff,s,0xff8800,c]                       // render
    },{animate:true,spin:.3,up:pviz}))
});
</SCRIPT></BODY>